﻿using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using MiniFox.Utility;
using MiniFox.Web.Configurations;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Converters;
using MiniFox.Infrastructure;

namespace MiniFox.Web.AppStarting
{
    /// <summary>
    /// 
    /// </summary>
    internal class RegisterMvc : HttpStartBase
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="configuration"></param>
        /// <param name="hostEnvironment"></param>
        /// <param name="webConfiguration"></param>
        public RegisterMvc(IConfiguration configuration, IWebHostEnvironment hostEnvironment, WebConfiguration webConfiguration) : base(configuration, hostEnvironment, webConfiguration)
        {
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="services"></param>
        public override void OnServicesConfiguring(IServiceCollection services)
        {
            Action<MvcOptions> action = options =>
            {
                if (this.WebConfiguration != null && this.WebConfiguration.Filters != null)
                    WebConfiguration.Filters.ForEach(providerSetting =>
                    {
                        Type type = providerSetting;
                        if (type.IsAssignableTo(typeof(IFilterMetadata)))
                            options.Filters.Add(type);
                    });

            };

            IMvcBuilder mvcBuilder;
            switch (WebConfiguration.ServerMode)
            {
                case ServerMode.WebApi:
                    mvcBuilder = services.AddControllers(action);
                    break;
                case ServerMode.WebMvc:
                default:
                    mvcBuilder = services.AddControllersWithViews(action);
                    break;
            }
            mvcBuilder.AddNewtonsoftJson((options) =>
            {
                options.SerializerSettings.Converters.Add(new DateTimeJsonConverter());
                options.SerializerSettings.Converters.Add(new StringEnumConverter());
                
                if (this.WebConfiguration.UseCamelCaseOnJsonSerialize)
                    options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            });
            mvcBuilder.ConfigureApplicationPartManager(manager =>
            {
                this.GetAssemblies().ForEach(assembly =>
                {
                    manager.ApplicationParts.Add(new AssemblyPart(assembly));
                    manager.ApplicationParts.Add(new CompiledRazorAssemblyPart(assembly));
                });
            });
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="app"></param>
        public override void OnApplicationConfiguring(IApplicationBuilder app)
        {
            app.UseRouting();
        }
    }
}
